package com.rocksea.app.db.SonicWave;

import android.util.Log;

import com.alibaba.fastjson.JSON;
import com.litesuits.orm.db.annotation.Default;
import com.litesuits.orm.db.annotation.Ignore;
import com.litesuits.orm.db.annotation.Mapping;
import com.litesuits.orm.db.annotation.PrimaryKey;
import com.litesuits.orm.db.annotation.Table;
import com.litesuits.orm.db.enums.AssignType;
import com.litesuits.orm.db.enums.Relation;
import com.mor.dataacquisition.vo.sonicWave.SonicWaveData;
import com.mor.dataacquisition.vo.sonicWave.SonicWaveFace;
import com.rocksea.app.Account;
import com.rocksea.app.entry.ScData;
import com.rocksea.app.http.HttpUtil;
import com.rocksea.app.utils.PerUtils;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

/**
 * Created by Mrw on 2017/8/5.
 *
 */
@Table("SonicWave")
public class SonicWave {
    @PrimaryKey(AssignType.AUTO_INCREMENT)
    private int id;
    @Ignore
    public String randomCode;
    @Ignore
    public String account;

    public long inspectionFormId;

    public String inspectionFormNum;

    public long pileId;

    @Default("0")
    public int isLoad;
    public long loadTime;
    public long revicedTime;

    public String uuid;
    public String vendorID;
    public String machineId;
    public String serialNo;
    public String pileNo;
    public int standard;
    public String startTime;
    public String fileName;
    public int pileDiameter;
    public double pileLength;
    public int step;
    public int totalPipe;
    public float sampleInterval;
    public int samplePoints;
    public int aDBytes;
    public int angle;
    public int highFilter;
    public int lowFilter;
    public double ampRatio;
    public String customParam;
    public int sectionCount;
    public String coordinateX;
    public String coordinateY;

    @Default("-1")
    public long serviceId;

    @Default("0")
    public long upLoadTime;
    public long creatTime;

    @Mapping(Relation.OneToMany)
    public ArrayList<SonicWaveFace> SonicWaveFaces;

    @Mapping(Relation.OneToMany)
    public ArrayList<SonicWaveData> SonicWaveDatas;
    public byte GpsIsValid;

    public SonicWave() {
    }

    public SonicWave(String json) {
        ScData mScData = JSON.parseObject(json, ScData.class);

        pileId = mScData.pileId;
        inspectionFormId = mScData.inspectionFormId;
        inspectionFormNum = mScData.inspectionFormNum;

        uuid = mScData.BaseInfoId;
        creatTime = new Date().getTime();
        vendorID = mScData.VendorID;
        machineId = mScData.MachineId;
        serialNo = mScData.SerialNo;
        pileNo = mScData.PileNo;
        standard = mScData.Standard;
        startTime = mScData.StartTime;
        fileName = mScData.FileName;
        pileDiameter = mScData.PileDiameter;
        pileLength = mScData.PileLength;
        step = (int) mScData.Step;
        totalPipe = mScData.TotalPipe;
        sampleInterval = (float) mScData.SampleInterval;
        samplePoints = mScData.SamplePoints;
        aDBytes = mScData.ADBytes;
        angle = mScData.Angle;
        highFilter = mScData.HighFilter;
        lowFilter = mScData.LowFilter;
        ampRatio = mScData.AmpRatio;
        customParam = JSON.toJSON(mScData.CustomParam).toString();
        sectionCount = mScData.CustomParam.SectionCount;
        coordinateX = HttpUtil.encyptDES(mScData.coordinateX + "");
        coordinateY = HttpUtil.encyptDES(mScData.coordinateY + "");

        HashMap<String, Integer> sectionId_tudedistance = new HashMap<>();

        if (mScData.SectionInfo != null) {
            List<ScData.SectionInfoBean> mSectionInfos = mScData.SectionInfo;
            SonicWaveFaces = new ArrayList<>();
            for (int i = 0; i < mSectionInfos.size(); i++) {
                SonicWaveFace mSonicWaveFace = new SonicWaveFace();
                ScData.SectionInfoBean mSection = mSectionInfos.get(i);

                mSonicWaveFace.baseInfoId = mSection.BaseInfoId;
                mSonicWaveFace.sectionId = mSection.SectionId;

                mSonicWaveFace.zeroTime = mSection.ZeroTime;
                mSonicWaveFace.initialDepth = mSection.InitialDepth;
                mSonicWaveFace.sensorDE = mSection.SensorDE;
                mSonicWaveFace.nodesCount = mSection.NodesCount;
                mSonicWaveFace.sectionNo = mSection.SectionNo;
                mSonicWaveFace.tubeDistance = mSection.TubeDistance;

                sectionId_tudedistance.put(mSection.SectionId, mSection.TubeDistance);

                mSonicWaveFace.testMode = mSection.TestMode;

                mSonicWaveFace.AC = (int) mSection.AC;
                mSonicWaveFace.avgA = (int) mSection.AvgA;
                mSonicWaveFace.avgF = (int) mSection.AvgF;
                mSonicWaveFace.avgV = (int) mSection.AvgV;
                mSonicWaveFace.cveAmp = mSection.CveAmp;
                mSonicWaveFace.cveFreq = mSection.CveFreq;
                mSonicWaveFace.cveV = mSection.CveV;
                mSonicWaveFace.minA = mSection.MinA;
                mSonicWaveFace.minV = mSection.MinV;
                mSonicWaveFace.VC = (int) mSection.VC;
                mSonicWaveFace.FC = (int) mSection.FC;
                mSonicWaveFace.SV = (int) mSection.SV;
                mSonicWaveFace.SA = (int) mSection.SA;
                mSonicWaveFace.SF = (int) mSection.SF;
                mSonicWaveFace.depth = mSection.Depth;
                mSonicWaveFace.homogeneity = String.format("%d", mSection.Homogeneity);
                SonicWaveFaces.add(mSonicWaveFace);
            }
        }
        if (mScData.data != null) {
            List<ScData.DataBean> mWaveData = mScData.data;
            SonicWaveDatas = new ArrayList<>();
            for (int i = 0; i < mWaveData.size(); i++) {
                SonicWaveData mSonicWaveData = new SonicWaveData();
                ScData.DataBean data = mWaveData.get(i);

                mSonicWaveData.sonicWaveId = i;
                mSonicWaveData.uuid = data.uuid;
                mSonicWaveData.curValidData = (mWaveData.size() / sectionCount * i + 1);
                mSonicWaveData.sectionId = data.SectionId;
                mSonicWaveData.depth = (int) (data.Depth * 1000);
                mSonicWaveData.sampleTime = startTime;
                mSonicWaveData.gain = data.Gain;
                mSonicWaveData.delay = data.Delay;
                mSonicWaveData.sWMaxI = data.SWMaxI;
                mSonicWaveData.T1 = data.T1;
                mSonicWaveData.T = data.T;
                if (sectionId_tudedistance.get(data.SectionId) != null) {
                    mSonicWaveData.V = (int) (sectionId_tudedistance.get(data.SectionId) / (float) data.T) * 1000;
                } else {
                    mSonicWaveData.V = 9999;
                }
                mSonicWaveData.A = data.A;
                mSonicWaveData.P = data.P;
                mSonicWaveData.PSD = data.PSD;
                mSonicWaveData.waveData = new Integer[data.WaveData.size()];
                for (int i1 = 0; i1 < data.WaveData.size(); i1++)
                    mSonicWaveData.waveData[i1] = data.WaveData.get(i1);
                SonicWaveDatas.add(mSonicWaveData);
            }
        }
    }

    @Table("SonicWaveFace")
    public static class SonicWaveFace {
        @PrimaryKey(AssignType.AUTO_INCREMENT)
        private int id;

        public String baseInfoId;
        public String sectionId;
        public int testMode;
        public String sectionNo;
        public int tubeDistance;
        public int sensorDE;
        public double zeroTime;
        public double initialDepth;
        public int nodesCount;
        public int avgV;
        public int avgA;
        public int avgF;
        public int minV;
        public int minA;
        public int VC;
        public int AC;
        public int FC;
        public int SV;
        public int SA;
        public int SF;
        public double cveV;
        public double cveAmp;
        public double cveFreq;
        public String homogeneity;
        public double depth;

        @Default("0")
        public long upLoadTime;
        public long creatTime;


        @Ignore
        public List<SonicWaveFace> sonicWaveFaces;

        public SonicWaveFace() {
        }

        public SonicWaveFace(String json) {
            sonicWaveFaces = new ArrayList<>();
            try {
                JSONArray jsonArray = new JSONArray(json);
                for (int i = 0; i < jsonArray.length(); i++) {
                    ScData.SectionInfoBean mSection = JSON.parseObject(jsonArray.getJSONObject(i).toString(), ScData.SectionInfoBean.class);
                    SonicWaveFace mSonicWaveFace = new SonicWaveFace();

                    mSonicWaveFace.baseInfoId = mSection.BaseInfoId;
                    mSonicWaveFace.sectionId = mSection.SectionId;

                    mSonicWaveFace.zeroTime = mSection.ZeroTime;
                    mSonicWaveFace.initialDepth = mSection.InitialDepth;
                    mSonicWaveFace.sensorDE = mSection.SensorDE;
                    mSonicWaveFace.nodesCount = mSection.NodesCount;
                    mSonicWaveFace.sectionNo = mSection.SectionNo;
                    mSonicWaveFace.tubeDistance = mSection.TubeDistance;
                    mSonicWaveFace.testMode = mSection.TestMode;

                    mSonicWaveFace.AC = (int) mSection.AC;
                    mSonicWaveFace.avgA = (int) mSection.AvgA;
                    mSonicWaveFace.avgF = (int) mSection.AvgF;
                    mSonicWaveFace.avgV = (int) mSection.AvgV;
                    mSonicWaveFace.cveAmp = mSection.CveAmp;
                    mSonicWaveFace.cveFreq = mSection.CveFreq;
                    mSonicWaveFace.cveV = mSection.CveV;
                    mSonicWaveFace.minA = mSection.MinA;
                    mSonicWaveFace.minV = mSection.MinV;
                    mSonicWaveFace.VC = (int) mSection.VC;
                    mSonicWaveFace.FC = (int) mSection.FC;
                    mSonicWaveFace.SV = (int) mSection.SV;
                    mSonicWaveFace.SA = (int) mSection.SA;
                    mSonicWaveFace.SF = (int) mSection.SF;
                    mSonicWaveFace.depth = mSection.Depth;
                    mSonicWaveFace.homogeneity = String.format("%d", mSection.Homogeneity);
                    sonicWaveFaces.add(mSonicWaveFace);
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }

        public List<SonicWaveFace> getSonicWaveFaces() {
            return sonicWaveFaces;
        }
    }


    @Table("SonicWaveData")
    public static class SonicWaveData {
        @PrimaryKey(AssignType.AUTO_INCREMENT)
        private int id;
        @Ignore
        public String randomcode;
        @Ignore
        public String account;

        public long sonicWaveId;
        public int curValidData;
        public String sectionId;
        public String uuid;
        public int depth;
        public String sampleTime;
        public double gain;
        public double delay;
        public int sWMaxI;
        public int T1;
        public double T;
        public float V;
        public float A;
        public float P;
        public double PSD;
        public float RecvHeight;

        @Default("0")
        public byte isValid;

        public Integer[] waveData;

        @Default("0")
        public long upLoadTime;
        public long creatTime;


        @Ignore
        public List<SonicWaveData> sonicWaveDatas;

        public SonicWaveData() {
        }

        public SonicWaveData(String json)
        {
            sonicWaveDatas = new ArrayList<>();
            List<ScData.DataBean> dataList = JSON.parseArray(json, ScData.DataBean.class);
            for (int i = 0; i < dataList.size(); i++) {
                ScData.DataBean data = dataList.get(i);
                SonicWaveData mSonicWaveData = new SonicWaveData();
                mSonicWaveData.sonicWaveId = -1;
                mSonicWaveData.uuid = data.uuid;
                mSonicWaveData.curValidData = i;
                mSonicWaveData.sectionId = data.SectionId;
                mSonicWaveData.depth = (int) (data.Depth * 1000);
                mSonicWaveData.sampleTime = data.SampleTime;
                mSonicWaveData.gain = data.Gain;
                mSonicWaveData.delay = data.Delay;
                mSonicWaveData.sWMaxI = data.SWMaxI;
                mSonicWaveData.T1 = data.T1;
                mSonicWaveData.T = data.T;
                mSonicWaveData.V = data.P;
                mSonicWaveData.A = data.A;
                mSonicWaveData.P = data.P;
                mSonicWaveData.PSD = data.PSD;
                mSonicWaveData.RecvHeight = data.RecvHeight;
                mSonicWaveData.creatTime = new Date().getTime();
                mSonicWaveData.waveData = new Integer[data.WaveData.size()];
                for (int i1 = 0; i1 < data.WaveData.size(); i1++)
                    mSonicWaveData.waveData[i1] = data.WaveData.get(i1);
                sonicWaveDatas.add(mSonicWaveData);
            }
        }

        public List<SonicWaveData> getSonicWaveDatas() {
            return sonicWaveDatas;
        }
    }

    private static List<SonicWave.SonicWaveData> parseSonicWave(String json)
    {
        List<SonicWave.SonicWaveData> sonicWaveData = new ArrayList<>();
        try
        {
            JSONArray jsonArray = new JSONArray(json);
            for (int i = 0; i < jsonArray.length(); i++)
            {
                JSONObject dataObject = jsonArray.getJSONObject(i);

                SonicWaveData mSonicWaveData = new SonicWaveData();
                mSonicWaveData.sonicWaveId = -1;
                mSonicWaveData.uuid = dataObject.getString("uuid");
                mSonicWaveData.curValidData = i;
                mSonicWaveData.sectionId = dataObject.getString("SectionId");
                mSonicWaveData.depth = (int)(dataObject.getDouble("Depth") * 1000);
                mSonicWaveData.sampleTime = dataObject.getString("SampleTime");
                mSonicWaveData.gain = dataObject.getDouble("Gain");
                mSonicWaveData.delay = dataObject.getDouble("Delay");
                mSonicWaveData.sWMaxI = dataObject.getInt("SWMaxI");
                mSonicWaveData.T1 = dataObject.getInt("T1");
                mSonicWaveData.T = dataObject.getInt("T");
                mSonicWaveData.V = dataObject.getInt("P");
                mSonicWaveData.A = dataObject.getInt("A");
                mSonicWaveData.P = dataObject.getInt("P");
                mSonicWaveData.PSD =dataObject.getInt("PSD");
                mSonicWaveData.RecvHeight = (float) dataObject.getDouble("RecvHeight");
                mSonicWaveData.creatTime = new Date().getTime();
                JSONArray waveData =  dataObject.getJSONArray("WaveData");
                mSonicWaveData.waveData = new Integer[waveData.length()];

                for (int i1 = 0; i1 < waveData.length(); i1++)
                {
                    mSonicWaveData.waveData[i1] = waveData.getInt(i1);
                }
                sonicWaveData.add(mSonicWaveData);
            }
        }
        catch (JSONException e)
        {
            e.printStackTrace();
        }
        return sonicWaveData;
    }




    public com.mor.dataacquisition.vo.sonicWave.SonicWave getBJTKSonicWave(int inspectionFormId,String inspectionFormNum,long pileId)
    {
        com.mor.dataacquisition.vo.sonicWave.SonicWave sonicWave
                = new com.mor.dataacquisition.vo.sonicWave.SonicWave();

        sonicWave.account = Account.getAccount();
        sonicWave.randomCode = Account.getRandomCode();
        sonicWave.inspectionFormId = inspectionFormId;
        sonicWave.inspectionFormNum = inspectionFormNum;
        sonicWave.pileId = pileId;

        sonicWave.vendorId = vendorID;
        sonicWave.machineId = machineId;
        sonicWave.serialNo = "RSSC";
        sonicWave.pileNo = pileNo;
        sonicWave.standard = standard;
        sonicWave.startTime = startTime;
        Log.i("getBJTKSonicWave: ","startTime = "+startTime);
        //sonicWave.startTime = PerUtils.dateToStr(new Date());//todo
        sonicWave.fileName = fileName;
        sonicWave.pileDiameter = pileDiameter;
        sonicWave.pileLength = pileLength;
        sonicWave.step = step;
        sonicWave.totalPipe = totalPipe;
        sonicWave.sampleInterval = PerUtils.getTwoData(sampleInterval);
        sonicWave.samplePoints = samplePoints;
        sonicWave.adBytes = aDBytes;
        sonicWave.angle = angle;
        if (highFilter > 99999)
            sonicWave.highFilter = 99999;
        else
            sonicWave.highFilter = highFilter;
        if (lowFilter > 99999)
            sonicWave.lowFilter = 99999;
        else
            sonicWave.lowFilter = lowFilter;
        Log.i("getBJTKSonicWave: ","lowFilter = "+lowFilter);
        //sonicWave.lowFilter = -1;

        DecimalFormat decimalFormat = new DecimalFormat("#0.000000");
        sonicWave.ampRatio = Double.parseDouble(decimalFormat.format(ampRatio));
        sonicWave.ampRatio = 9.123214;//TODO
        Log.i("getBJTKSonicWave: ","ampRatio = "+sonicWave.ampRatio);
        sonicWave.customParam = customParam;
        if (SonicWaveFaces != null)
            sonicWave.sectionCount = SonicWaveFaces.size();
        sonicWave.coordinateX = coordinateX;
        sonicWave.coordinateY = coordinateY;
        try {
            JSONObject customParamJSON = new JSONObject(sonicWave.customParam);
            sonicWave.transmitDiameter = (int) customParamJSON.getDouble("SensorOutDia");

        } catch (JSONException e) {
            e.printStackTrace();
        }
        if (sonicWave.transmitDiameter < 10)
            sonicWave.transmitDiameter = 30;

        sonicWave.voltage = 500;
        return sonicWave;
    }

    public  com.mor.dataacquisition.vo.sonicWave.SonicWaveFace getBJTKWaveFace(SonicWaveFace mData)
    {
        com.mor.dataacquisition.vo.sonicWave.SonicWaveFace waveFace =
                new com.mor.dataacquisition.vo.sonicWave.SonicWaveFace();
        waveFace.sectionId = mData.sectionId.replace("-","");
        waveFace.testMode = mData.testMode;

        if (mData.sectionNo.contains("-"))
        {
            waveFace.sectionNo = mData.sectionNo;
        }
        else
        {
            StringBuilder builder = new StringBuilder(mData.sectionNo);
            builder.insert(1,"-");
            waveFace.sectionNo = builder.toString();
        }

        waveFace.tubeDistance = mData.tubeDistance;
        waveFace.sensorDE = mData.sensorDE;
        if (mData.zeroTime > 99)
            waveFace.zeroTime = 99;
        else
            waveFace.zeroTime = mData.zeroTime;

        waveFace.initialDepth = mData.initialDepth;
        waveFace.nodesCount = mData.nodesCount;

        if (mData.avgV > 9999)
            waveFace.avgV = 9999;
        else
            waveFace.avgV = mData.avgV;
        if (mData.avgA > 999)
            waveFace.avgA = 999;
        else
            waveFace.avgA = mData.avgA;
        if (mData.avgF > 99999)
            waveFace.avgF = 99999;
        else
            waveFace.avgF = mData.avgF;
        if (mData.minV > 9999)
            waveFace.minV = 9999;
        else
            waveFace.minV = mData.minV;
        if (mData.minA > 999)
            waveFace.minA = 999;
        else
            waveFace.minA = mData.minA;
        if (mData.VC > 9999)
            waveFace.VC = 9999;
        else
            waveFace.VC = mData.VC;
        if (mData.AC > 999)
            waveFace.AC = 999;
        else
            waveFace.AC = mData.AC;
        if (mData.FC > 99999)
            waveFace.FC = 99999;
        else
            waveFace.FC = mData.FC;
        if (mData.SV > 9999)
            waveFace.SV = 9999;
        else
            waveFace.SV = mData.SV;
        if (mData.SA > 999)
            waveFace.SA = 999;
        else
            waveFace.SA = mData.SA;
        if (mData.SF > 99999)
            waveFace.SF = 99999;
        else
            waveFace.SF = mData.SF;
        if (mData.cveV > 999)
            waveFace.cveV = 999;
        else
            waveFace.cveV = PerUtils.getTwoData(mData.cveV);
        if (mData.cveAmp > 999)
            waveFace.cveAmp = 999;
        else
            waveFace.cveAmp = PerUtils.getTwoData(mData.cveAmp);
        if (mData.cveFreq > 999)
            waveFace.cveFreq = 999;
        else
            waveFace.cveFreq = PerUtils.getTwoData(mData.cveFreq);
        if (mData.homogeneity.length() > 4)
            waveFace.homogeneity = "1234";
        else
            waveFace.homogeneity = mData.homogeneity;
        if (mData.depth > 999)
            waveFace.depth = 999;
        else
            waveFace.depth = PerUtils.getTwoData(mData.depth);
        return waveFace;
    }

    public com.mor.dataacquisition.vo.sonicWave.SonicWaveData getBJTKWaveData(SonicWaveData mData,long sonicWaveId,HashMap<String,Integer> tude)
    {
        com.mor.dataacquisition.vo.sonicWave.SonicWaveData sonicWaveData
                = new com.mor.dataacquisition.vo.sonicWave.SonicWaveData();
        sonicWaveData. randomCode = Account.getRandomCode();
        sonicWaveData. account =Account.getAccount();

        sonicWaveData. sonicWaveId = sonicWaveId;
        sonicWaveData. curValidData = 1;
        sonicWaveData. sectionId = mData.sectionId.replace("-","");
        sonicWaveData. uuid = mData.uuid.replace("-","");

        sonicWaveData. depth = mData.depth;
        sonicWaveData. sampleTime = mData.sampleTime;
        if (mData.gain > 999)
            sonicWaveData.gain = 999.0;
        else
            sonicWaveData. gain = PerUtils.getTwoData(mData.gain);

        if (mData.delay > 999)
            sonicWaveData.delay = 999;
        else
            sonicWaveData. delay = PerUtils.getTwoData(mData.delay);
        sonicWaveData. sWMaxI = mData.sWMaxI;
        if (mData.T1 > 9999)
            mData.T1 = 9999;
        else if (mData.T1 < 0)
            sonicWaveData. T1 = 9999;
        else
            sonicWaveData. T1 = mData.T1;
        if (mData.T > 9999 || mData.T <= 0)
            sonicWaveData.T = 100;
        else
            sonicWaveData. T = PerUtils.getTwoData(mData.T);
        if (tude.get(mData.sectionId) != null)
        {
            sonicWaveData. V = (int) (tude.get(mData.sectionId)/mData.T*1000);
            if ( sonicWaveData.V > 9999)
                sonicWaveData.V = 9999;
        }
        else
            sonicWaveData. V = 9999;

        if (mData.A > 999)
        {
            sonicWaveData.A = 999;
        }
        else
            sonicWaveData. A = rounding(mData.A);
        if (mData.P > 99999)
            sonicWaveData.P = 99999;
        else
            sonicWaveData. P = rounding(mData.P);
        //DecimalFormat decimalFormat = new DecimalFormat("#.00");
        //sonicWaveData.PSD = PerUtils.getTwoData(Float.parseFloat(decimalFormat.format(mData.PSD)));
        if (mData.PSD > 999999 || mData.PSD < 0)
            sonicWaveData.PSD = 0.00;
        else
            sonicWaveData.PSD = formatDouble2(mData.PSD);
        sonicWaveData.waveData = new ArrayList<>();
        Collections.addAll(sonicWaveData.waveData, mData.waveData);
        return sonicWaveData;
    }

    public static double formatDouble2(double d)
    {
        // 新方法，如果不需要四舍五入，可以使用RoundingMode.DOWN
        BigDecimal bg = new BigDecimal(d).setScale(2, RoundingMode.UP);
        return bg.doubleValue();
    }

    private static int rounding(float value)
    {
        return  new BigDecimal(value).setScale(0, BigDecimal.ROUND_HALF_UP).intValue();
    }

}




